<!-- 实现微信服务号自动回复功能
1.被关注回复、收到消息回复、关键字回复三种自动回复类型。
2.回复内容支持文本、图片、语音、视频、文件、链接, 图文等。

数据库设计如下：
id 主键自增
replyType 自动回复类型 1.被关注回复 2.收到消息回复 3.关键字回复
replyContent 回复内容 文本、图片、语音、视频、文件、链接, 图文等
replyContentType 回复内容类型 1.文本 2.图片 3.语音 4.视频 5.音乐 6.图文
replyState 回复状态 1.启用 0.禁用
ctime 创建时间
utime 更新时间
dtime 删除时间 -->
<template>
  <div class="wechat-auto-reply-container">
    <div class="page-header">
      <h2>微信服务号自动回复设置</h2>
      <div class="header-actions">
        <el-button type="primary" @click="handleSave">保存设置</el-button>
        <el-button @click="handleReset">重置</el-button>
      </div>
    </div>

    <el-card class="reply-config-card">
      <div class="reply-type-tabs">
        <el-tabs v-model="activeTab" @tab-change="handleTabChange">
          <el-tab-pane label="被关注回复" name="1">
            <div class="reply-type-content">
              <div class="state-switch">
                <span>状态：</span>
                <el-switch 
                  v-model="replyConfigs[0].replyState" 
                  active-value="1" 
                  inactive-value="0"
                />
              </div>
              
              <div class="content-type-selector">
                <span>回复内容类型：</span>
                <el-select 
                  v-model="replyConfigs[0].replyContentType" 
                  placeholder="请选择回复内容类型"
                  @change="handleContentTypeChange(0)"
                >
                  <el-option label="文本" value="1" />
                  <el-option label="图片" value="2" />
                  <el-option label="语音" value="3" />
                  <el-option label="视频" value="4" />
                  <el-option label="音乐" value="5" />
                  <el-option label="图文" value="6" />
                </el-select>
              </div>

              <!-- 内容编辑区域 -->
              <div class="content-editor" v-if="replyConfigs[0].replyState === '1'">
                <!-- 文本内容 -->
                <div v-if="replyConfigs[0].replyContentType === '1'" class="content-item">
                  <el-input
                    type="textarea"
                    :rows="5"
                    placeholder="请输入文本内容"
                    v-model="replyConfigs[0].replyContent.text"
                  />
                  <div class="content-tips">支持最多600个汉字</div>
                </div>

                <!-- 图片内容 -->
                <div v-if="replyConfigs[0].replyContentType === '2'" class="content-item">
                  <el-upload
                    class="avatar-uploader"
                    action="#"
                    :show-file-list="false"
                    :on-success="handleImageSuccess"
                    :before-upload="beforeAvatarUpload"
                  >
                    <img v-if="replyConfigs[0].replyContent.imageUrl" :src="replyConfigs[0].replyContent.imageUrl" class="avatar">
                    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                  </el-upload>
                  <div class="content-tips">支持JPG、PNG格式，大小不超过2MB</div>
                </div>

                <!-- 语音内容 -->
                <div v-if="replyConfigs[0].replyContentType === '3'" class="content-item">
                  <el-upload
                    class="file-uploader"
                    action="#"
                    :show-file-list="true"
                    :on-success="handleVoiceSuccess"
                    accept=".mp3,.wma,.wav,.amr"
                  >
                    <el-button size="small" type="primary">点击上传</el-button>
                  </el-upload>
                  <div class="content-tips">支持MP3、WMA、WAV、AMR格式，大小不超过5MB，时长不超过60秒</div>
                </div>

                <!-- 视频内容 -->
                <div v-if="replyConfigs[0].replyContentType === '4'" class="content-item">
                  <el-upload
                    class="file-uploader"
                    action="#"
                    :show-file-list="true"
                    :on-success="handleVideoSuccess"
                    accept=".mp4"
                  >
                    <el-button size="small" type="primary">点击上传</el-button>
                  </el-upload>
                  <div class="content-tips">支持MP4格式，大小不超过10MB</div>
                </div>

                <!-- 音乐内容 -->
                <div v-if="replyConfigs[0].replyContentType === '5'" class="content-item">
                  <el-form :model="replyConfigs[0].replyContent">
                    <el-form-item label="标题" prop="title">
                      <el-input v-model="replyConfigs[0].replyContent.title" placeholder="请输入音乐标题" />
                    </el-form-item>
                    <el-form-item label="描述" prop="description">
                      <el-input v-model="replyConfigs[0].replyContent.description" placeholder="请输入音乐描述" />
                    </el-form-item>
                    <el-form-item label="音乐链接" prop="musicUrl">
                      <el-input v-model="replyConfigs[0].replyContent.musicUrl" placeholder="请输入音乐链接" />
                    </el-form-item>
                    <el-form-item label="HQ音乐链接" prop="hqMusicUrl">
                      <el-input v-model="replyConfigs[0].replyContent.hqMusicUrl" placeholder="请输入高品质音乐链接" />
                    </el-form-item>
                    <el-form-item label="缩略图" prop="thumbMediaId">
                      <el-upload
                        class="avatar-uploader"
                        action="#"
                        :show-file-list="false"
                        :on-success="handleThumbSuccess"
                        :before-upload="beforeAvatarUpload"
                      >
                        <img v-if="replyConfigs[0].replyContent.thumbUrl" :src="replyConfigs[0].replyContent.thumbUrl" class="avatar">
                        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                      </el-upload>
                    </el-form-item>
                  </el-form>
                </div>

                <!-- 图文内容 -->
                <div v-if="replyConfigs[0].replyContentType === '6'" class="content-item">
                  <el-button type="primary" size="small" @click="addNewsItem(0)">添加图文</el-button>
                  <div class="news-list">
                    <div v-for="(news, index) in replyConfigs[0].replyContent.newsList" :key="index" class="news-item">
                      <el-form :model="news">
                        <el-form-item label="标题" :prop="`newsList[${index}].title`">
                          <el-input v-model="news.title" placeholder="请输入标题" />
                        </el-form-item>
                        <el-form-item label="描述" :prop="`newsList[${index}].description`">
                          <el-input v-model="news.description" placeholder="请输入描述" />
                        </el-form-item>
                        <el-form-item label="图片" :prop="`newsList[${index}].picUrl`">
                          <el-upload
                            class="avatar-uploader"
                            action="#"
                            :show-file-list="false"
                            :on-success="(res) => handleNewsImageSuccess(res, 0, index)"
                            :before-upload="beforeAvatarUpload"
                          >
                            <img v-if="news.picUrl" :src="news.picUrl" class="avatar">
                            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                          </el-upload>
                        </el-form-item>
                        <el-form-item label="链接" :prop="`newsList[${index}].url`">
                          <el-input v-model="news.url" placeholder="请输入链接" />
                        </el-form-item>
                      </el-form>
                      <el-button type="danger" size="small" @click="removeNewsItem(0, index)">删除</el-button>
                    </div>
                  </div>
                  <div class="content-tips">最多支持8条图文消息</div>
                </div>
              </div>
            </div>
          </el-tab-pane>

          <el-tab-pane label="收到消息回复" name="2">
            <div class="reply-type-content">
              <div class="state-switch">
                <span>状态：</span>
                <el-switch 
                  v-model="replyConfigs[1].replyState" 
                  active-value="1" 
                  inactive-value="0"
                />
              </div>
              
              <div class="content-type-selector">
                <span>回复内容类型：</span>
                <el-select 
                  v-model="replyConfigs[1].replyContentType" 
                  placeholder="请选择回复内容类型"
                  @change="handleContentTypeChange(1)"
                >
                  <el-option label="文本" value="1" />
                  <el-option label="图片" value="2" />
                  <el-option label="语音" value="3" />
                  <el-option label="视频" value="4" />
                  <el-option label="音乐" value="5" />
                  <el-option label="图文" value="6" />
                </el-select>
              </div>

              <!-- 内容编辑区域 -->
              <div class="content-editor" v-if="replyConfigs[1].replyState === '1'">
                <!-- 文本内容 -->
                <div v-if="replyConfigs[1].replyContentType === '1'" class="content-item">
                  <el-input
                    type="textarea"
                    :rows="5"
                    placeholder="请输入文本内容"
                    v-model="replyConfigs[1].replyContent.text"
                  />
                  <div class="content-tips">支持最多600个汉字</div>
                </div>

                <!-- 其他内容类型的实现与被关注回复类似，这里省略 -->
                <div v-else class="content-item">
                  <el-alert
                    title="请选择内容类型并配置相关内容"
                    type="info"
                    show-icon
                  />
                </div>
              </div>
            </div>
          </el-tab-pane>

          <el-tab-pane label="关键字回复" name="3">
            <div class="reply-type-content">
              <el-button type="primary" size="small" @click="addKeywordReply">添加关键字回复</el-button>
              
              <div class="keyword-reply-list">
                <div v-for="(reply, index) in keywordReplies" :key="index" class="keyword-reply-item">
                  <el-card>
                    <div class="keyword-header">
                      <div class="keyword-title">
                        <span>关键字回复 #{{ index + 1 }}</span>
                        <el-switch 
                          v-model="reply.replyState" 
                          active-value="1" 
                          inactive-value="0"
                          style="margin-left: 20px;"
                        />
                      </div>
                      <el-button type="danger" size="small" @click="removeKeywordReply(index)">删除</el-button>
                    </div>
                    
                    <div class="keyword-config" v-if="reply.replyState === '1'">
                      <el-form :model="reply">
                        <el-form-item label="关键字">
                          <el-input v-model="reply.keywords" placeholder="多个关键字用逗号分隔" />
                        </el-form-item>
                        <el-form-item label="回复内容类型">
                          <el-select 
                            v-model="reply.replyContentType" 
                            placeholder="请选择回复内容类型"
                            @change="handleKeywordContentTypeChange(index)"
                          >
                            <el-option label="文本" value="1" />
                            <el-option label="图片" value="2" />
                            <el-option label="语音" value="3" />
                            <el-option label="视频" value="4" />
                            <el-option label="音乐" value="5" />
                            <el-option label="图文" value="6" />
                          </el-select>
                        </el-form-item>
                        
                        <!-- 关键字回复内容编辑区域 -->
                        <div class="content-editor">
                          <!-- 文本内容 -->
                          <div v-if="reply.replyContentType === '1'" class="content-item">
                            <el-input
                              type="textarea"
                              :rows="5"
                              placeholder="请输入文本内容"
                              v-model="reply.replyContent.text"
                            />
                            <div class="content-tips">支持最多600个汉字</div>
                          </div>
                          
                          <!-- 其他内容类型的实现类似，这里省略 -->
                          <div v-else class="content-item">
                            <el-alert
                              title="请选择内容类型并配置相关内容"
                              type="info"
                              show-icon
                            />
                          </div>
                        </div>
                      </el-form>
                    </div>
                  </el-card>
                </div>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue';
import { ElMessage } from 'element-plus';

// 活动标签页
const activeTab = ref('1');

// 被关注回复和收到消息回复的配置
const replyConfigs = reactive([
  // 被关注回复
  {
    id: '',
    replyType: '1',
    replyContent: { text: '' },
    replyContentType: '1',
    replyState: '0',
    ctime: '',
    utime: '',
    dtime: ''
  },
  // 收到消息回复
  {
    id: '',
    replyType: '2',
    replyContent: { text: '' },
    replyContentType: '1',
    replyState: '0',
    ctime: '',
    utime: '',
    dtime: ''
  }
]);

// 关键字回复列表
const keywordReplies = reactive([]);

// 切换标签页
const handleTabChange = (tabName) => {
  activeTab.value = tabName;
};

// 处理内容类型变化
const handleContentTypeChange = (index) => {
  // 重置回复内容
  const contentType = replyConfigs[index].replyContentType;
  switch (contentType) {
    case '1':
      replyConfigs[index].replyContent = { text: '' };
      break;
    case '2':
      replyConfigs[index].replyContent = { imageUrl: '' };
      break;
    case '3':
      replyConfigs[index].replyContent = { voiceUrl: '' };
      break;
    case '4':
      replyConfigs[index].replyContent = { videoUrl: '' };
      break;
    case '5':
      replyConfigs[index].replyContent = {
        title: '',
        description: '',
        musicUrl: '',
        hqMusicUrl: '',
        thumbMediaId: '',
        thumbUrl: ''
      };
      break;
    case '6':
      replyConfigs[index].replyContent = { newsList: [] };
      break;
  }
};

// 处理关键字内容类型变化
const handleKeywordContentTypeChange = (index) => {
  const contentType = keywordReplies[index].replyContentType;
  switch (contentType) {
    case '1':
      keywordReplies[index].replyContent = { text: '' };
      break;
    case '2':
      keywordReplies[index].replyContent = { imageUrl: '' };
      break;
    case '3':
      keywordReplies[index].replyContent = { voiceUrl: '' };
      break;
    case '4':
      keywordReplies[index].replyContent = { videoUrl: '' };
      break;
    case '5':
      keywordReplies[index].replyContent = {
        title: '',
        description: '',
        musicUrl: '',
        hqMusicUrl: '',
        thumbMediaId: '',
        thumbUrl: ''
      };
      break;
    case '6':
      keywordReplies[index].replyContent = { newsList: [] };
      break;
  }
};

// 添加关键字回复
const addKeywordReply = () => {
  const newReply = {
    id: '',
    replyType: '3',
    keywords: '',
    replyContent: { text: '' },
    replyContentType: '1',
    replyState: '0',
    ctime: '',
    utime: '',
    dtime: ''
  };
  keywordReplies.push(newReply);
};

// 删除关键字回复
const removeKeywordReply = (index) => {
  keywordReplies.splice(index, 1);
};

// 添加图文项
const addNewsItem = (configIndex) => {
  const newsList = replyConfigs[configIndex].replyContent.newsList || [];
  if (newsList.length >= 8) {
    ElMessage.warning('最多支持8条图文消息');
    return;
  }
  const newNews = {
    title: '',
    description: '',
    picUrl: '',
    url: ''
  };
  newsList.push(newNews);
};

// 删除图文项
const removeNewsItem = (configIndex, newsIndex) => {
  replyConfigs[configIndex].replyContent.newsList.splice(newsIndex, 1);
};

// 图片上传成功处理
const handleImageSuccess = (response, file, fileList) => {
  // 实际项目中需要根据返回的response设置图片地址
  replyConfigs[0].replyContent.imageUrl = URL.createObjectURL(file.raw);
};

// 语音上传成功处理
const handleVoiceSuccess = (response, file, fileList) => {
  // 实际项目中需要根据返回的response设置语音地址
  replyConfigs[0].replyContent.voiceUrl = file.name;
};

// 视频上传成功处理
const handleVideoSuccess = (response, file, fileList) => {
  // 实际项目中需要根据返回的response设置视频地址
  replyConfigs[0].replyContent.videoUrl = file.name;
};

// 缩略图上传成功处理
const handleThumbSuccess = (response, file, fileList) => {
  // 实际项目中需要根据返回的response设置缩略图地址
  replyConfigs[0].replyContent.thumbUrl = URL.createObjectURL(file.raw);
};

// 图文图片上传成功处理
const handleNewsImageSuccess = (response, configIndex, newsIndex, file, fileList) => {
  // 实际项目中需要根据返回的response设置图片地址
  replyConfigs[configIndex].replyContent.newsList[newsIndex].picUrl = URL.createObjectURL(file.raw);
};

// 图片上传前检查
const beforeAvatarUpload = (file) => {
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    ElMessage.error('上传图片大小不能超过 2MB!');
    return false;
  }
  return true;
};

// 保存设置
const handleSave = () => {
  // 收集所有设置
  const allSettings = [
    ...replyConfigs,
    ...keywordReplies
  ];
  
  // 转换为数据库格式
  const formattedData = allSettings.map(setting => {
    return {
      id: setting.id,
      replyType: setting.replyType,
      replyContent: JSON.stringify(setting.replyContent),
      replyContentType: setting.replyContentType,
      replyState: setting.replyState,
      // 关键字回复特有字段
      keywords: setting.keywords || null
    };
  });
  
  // 这里应该调用API保存数据
  console.log('保存的数据:', formattedData);
  ElMessage.success('设置保存成功');
};

// 重置设置
const handleReset = () => {
  // 重置被关注回复和收到消息回复
  replyConfigs[0] = {
    id: '',
    replyType: '1',
    replyContent: { text: '' },
    replyContentType: '1',
    replyState: '0',
    ctime: '',
    utime: '',
    dtime: ''
  };
  replyConfigs[1] = {
    id: '',
    replyType: '2',
    replyContent: { text: '' },
    replyContentType: '1',
    replyState: '0',
    ctime: '',
    utime: '',
    dtime: ''
  };
  
  // 清空关键字回复
  keywordReplies.length = 0;
  
  ElMessage.info('设置已重置');
};

// 初始化页面数据
onMounted(() => {
  // 这里应该调用API获取已保存的设置数据
  // 目前使用模拟数据
  console.log('初始化页面数据');
});
</script>

<style scoped lang="scss">
.wechat-auto-reply-container {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.reply-config-card {
  background-color: #fff;
  border-radius: 4px;
  overflow: hidden;
}

.reply-type-tabs {
  padding: 20px;
}

.reply-type-content {
  margin-top: 20px;
}

.state-switch {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.content-type-selector {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.content-editor {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 15px;
}

.content-item {
  margin-bottom: 10px;
}

.content-tips {
  color: #909399;
  font-size: 12px;
  margin-top: 5px;
}

/* 图片上传样式 */
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}

.avatar {
  width: 178px;
  height: 178px;
  display: block;
}

.file-uploader {
  margin-bottom: 10px;
}

/* 关键字回复样式 */
.keyword-reply-list {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.keyword-reply-item {
  animation: fadeIn 0.3s ease-in-out;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.keyword-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.keyword-title {
  display: flex;
  align-items: center;
  font-weight: 500;
}

.keyword-config {
  margin-top: 10px;
}

/* 图文列表样式 */
.news-list {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.news-item {
  padding: 15px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  position: relative;
}

.news-item .el-button {
  position: absolute;
  top: 10px;
  right: 10px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .wechat-auto-reply-container {
    padding: 10px;
  }
  
  .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 15px;
  }
  
  .header-actions {
    width: 100%;
    justify-content: flex-end;
  }
  
  .state-switch,
  .content-type-selector {
    flex-direction: column;
    align-items: flex-start;
    gap: 5px;
  }
}
</style>